package sistema;
import java.util.*;

import notas.Nota;

import callForPapers.*;
import estadosPaper.Estado;
import estadosUsuario.EstadoUsuario;




public class Usuario {
	// Variables de instancia:
	private Calendar fechaDeAlta;
	private String nombre;
	private String apellido;
	private String userName;
	private String password;
	private String email;
	private Set<AreaDeInteres> areasDeInteres;
	private Set<Paper> papersARevisar;
	private Sistema sistema;
	private EstadoUsuario estado;
	
	/////////////////////////////////////////////////////////////////////////////////////////////
	
	// Constructor
		public Usuario(String nombre, String apellido, String userName, String password, String email,
					Calendar fechaDeAlta, Set<AreaDeInteres> areasDeInteres) {
			this.setNombre (nombre);
			this.setApellido (apellido);
			this.setUserName (userName);
			this.setPassword (password);
			this.setEmail (email);
			this.setFecha (fechaDeAlta);
			this.setAreas (areasDeInteres);
			this.papersARevisar = new HashSet<Paper>();
			this.sistema = Sistema.getInstance();
			
		}
		
		public Usuario(String nombre, String apellido, String userName, String password, String email,
				Calendar fechaDeAlta, AreaDeInteres areasDeInteres) {
		this.setNombre (nombre);
		this.setApellido (apellido);
		this.setUserName (userName);
		this.setPassword (password);
		this.setEmail (email);
		this.setFecha (fechaDeAlta);
		this.areasDeInteres = new HashSet<AreaDeInteres>();
		this.areasDeInteres.add(areasDeInteres);
		this.papersARevisar = new HashSet<Paper>();
		this.sistema = Sistema.getInstance();
		
	}
	
	////////////////////////////////////////////////////////////////////////////////////////
	
	// getters y seters
	
	public Calendar getFechaDeAlta() {
		return fechaDeAlta;
	}

	public EstadoUsuario getEstado() {
		return estado;
	}

	public void setEstado(EstadoUsuario estado) {
		this.estado = estado;
	}

	public void setFechaDeAlta(Calendar fechaDeAlta) {
		this.fechaDeAlta = fechaDeAlta;
	}

	public Set<Paper> getPapersARevisar() {
		return this.papersARevisar;
	}

	public void setPapersARevisar(Set<Paper> papersARevisar) {
		this.papersARevisar = papersARevisar;
	}

	public void setAreasDeInteres(Set<AreaDeInteres> areasDeInteres) {
		this.areasDeInteres = areasDeInteres;
	}

	public void setFecha(Calendar fecha){ this.fechaDeAlta = fecha; }
	
	public Calendar getFecha(){	return this.fechaDeAlta; }
	
	private void setAreas(Set<AreaDeInteres> areasDeInteres2) { this.areasDeInteres = areasDeInteres2; }
	
	public Set<AreaDeInteres> getAreasDeInteres() { return this.areasDeInteres; }
	
	public String getNombre() { return nombre; }
	
	public void setNombre(String nombre) { this.nombre = nombre; }
	
	public String getApellido() { return apellido; }
	
	public void setApellido(String apellido) { this.apellido = apellido; }
	
	public String getUserName() { return userName; }
	
	public void setUserName(String userName) { this.userName = userName; }
	
	public String getPassword() { return password; }
	
	public void setPassword(String password) { this.password = password; }
	
	public String getEmail() { return email; }
	
	public void setEmail(String email) { this.email = email; }
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * lista de call for papers donde pueso mandar trabajos ya que comparto areas en comun
	 * @return
	 */
	public List<CallForPaper> cfpDondePuedoMandarTrabajos(){
		
		List<CallForPaper> listaCfps = new ArrayList<CallForPaper>();
		
		for ( CallForPaper cfp : this.sistema.getCfps() ) {
			 if(cfp.tieneAreaEnComun(this)) {
				 listaCfps.add(cfp);
			 }
		}
		
		return listaCfps;
}
	
	public void crearCallForPaper(String nombre, Calendar fechaTopeDePresentacion,
			Calendar fechaTopeRevision, Set<AreaDeInteres> areasDeInteres ) {
		
				this.getEstado().crearCallForPaper(nombre, fechaTopeDePresentacion, fechaTopeRevision, areasDeInteres, this);
	}
	
	public void crearCallForPaper(String nombre, Calendar fechaTopeDePresentacion,
			Calendar fechaTopeRevision, AreaDeInteres areasDeInteres ) {
		
		this.getEstado().crearCallForPaper(nombre, fechaTopeDePresentacion, fechaTopeRevision, areasDeInteres, this);
	}

	/**
	 * muestra todos los posibles revisores que puedo seleccionar para el cfp dado
	 * siendo el cfp dado un cfp que yo aya creado
	 * @param callForPaper
	 * @return
	 */
	public List<Usuario> filtrarRevisoresPorAfinidad(CallForPaper callForPaper) {
		return this.getEstado().filtrarRevisoresPorAfinidad(callForPaper);
		
	}
	
	/**
	 * agrega un revisor al cfp dado
	 * @param usuario
	 * @param cfp
	 */
	public void agregarRevisor(Usuario usuario, CallForPaper cfp) {
		
		if(cfp.soyDueno(this)) {
		this.getEstado().agregarRevisor(usuario,cfp);
		}
		else {
			try {
				throw new Exception("No tienes privilegios, no sos creador del cfp");
			} catch (Exception e) {
				e.getMessage();
			}
		}
		
	}

	/**
	 * muestra las diferentes asiganciones en todos los cfp que tengo alguna relacion
	 * "soy revisor "  y lista de cfps
	 * "soy autor" y lista de cfps
	 * @return
	 */
	public Map<String, Set<CallForPaper>> verAsignacionesACFP(){

		return this.getEstado().verAsignacionesACFP(this);

		}
	
	/**
	 * muestra los papers y su estados de revision donde el usuario es autor
	 * @param cfp
	 * @return
	 */
	public Map<Paper,Estado> verPapersYEstadosComoAutor(CallForPaper cfp){
	
		return this.getEstado().verPapersYEstadosComoAutor(cfp, this);
		
	}
	
	/**
	 * muestra los papers en el cfp que tengo asignados para revisar
	 * si es que el cfp alcanzo su fecha tope de presentacion
	 * @param cfp
	 * @return
	 */
	public List<Paper> verPapersComoRevisor(CallForPaper cfp){
		
		return this.getEstado().verPapersComoRevisor(cfp,this);		
		}
	
	/**
	 * muestra las notas y los comentarios de un paper dado
	 * @param paper
	 * @return
	 */
	public Map<String,String> verNotasYComentarios(Paper paper) {
				
		return this.getEstado().verNotasYComentarios(paper);
	}
	
	/**
	 * permite al usuario calificar un paper dado
	 */
	public void calificarPaper(Paper paper, String comentario, Nota nota) {
		
	this.getEstado().calificarPaper(paper, comentario, nota);
	}
	
	public void desLoguearse() {
	this.getEstado().desLoguerse(this);
	}
	
	public void loguearse(String nombre, String password) {
		this.getEstado().loguearse(nombre,password);
	}
	
	/**
	 * true si el usuario tiene una area en comun con el cfp pasado
	 * @param cfp
	 * @return
	 */
	public boolean tieneAreaEnComun(CallForPaper cfp) {
		
		for(AreaDeInteres areaAComparar : cfp.getAreasDeInteres()) {
			if(areaAComparar.isIncluded(this.getAreasDeInteres())) {
				return true;
			}			
		}
		return false;
}

}

